<?php

namespace app\controller;

use app\BaseController;
use Exception;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\response\Json;

class Bbs extends BaseController
{
    /**
     * 获取置顶帖
     */
    public function top_list(): Json
    {
        try {
            $uid = $this->getUid();

            $obj = $this->M("bbs")
                ->alias('b')
                ->field('b.id, b.top, b.cate_id, b.title, u.nickname, u.head_img, substring(b.content, 1, 100) as summary, b.view_num as views, b.good_num as likes, b.bad_num as dislikes, b.comment_num as comments, b.create_time as time,b.uid, b.cover_src as cover, ur.role_id as role, bg.id as is_good')
                ->leftJoin('user_role ur', 'ur.uid = b.uid')
                ->leftJoin('bbs_good bg', 'bg.bid = b.id AND bg.uid = ' . $uid)
                ->leftJoin('category cate', 'b.cate_id = cate.id')
                ->join('user u', 'u.id = b.uid')
                ->order("b.top", "desc");

            $obj->where([['b.stat', '=', 1],['b.top', '=', 1], ['cate.stat', '=', 1]])
                ->group('b.id, u.nickname, u.head_img, bg.id');

            $count = $obj->count();
            $list = $obj->order('b.top_time', 'desc')
                ->select()
                ->toArray();

            $data = [];
            $data['_extra'] = ['sum' => ['total' => $count]];

            foreach ($list as $v) {
                $liked = $v['is_good'] != null;
                $item = [
                    'id' => $v['id'],
                    'cate_id' => $v['cate_id'],
                    'uid' => $v['uid'],
                    'title' => $v['title'],
                    'summary' => $v['summary'],
                    'cover' => $v['cover'],
                    'time' => $v['time'],
                    'likes' => $v['likes'],
                    'dislikes' => $v['dislikes'],
                    'comments' => $v['comments'],
                    'views' => $v['views'],
                    'like' => $liked ? 1 : 0,
                    'top' => $v['top']
                ];
                $item['author'] = [
                    'nickname' => $v['nickname'],
                    'headurl' => $v['head_img'],
                    'role' => $v['role']
                ];
                $data[] = $item;
            }

            return pr(200, API_SUCCESS, $data);
        } catch (Exception $e) {
            return pr(301, $e->getMessage());
        }
    }
    /**
     * 获取帖子列表
     */
    public function list($id): Json
    {
        try {
            $uid = $this->getUid();
            $search = request()->post('search');
            $page = request()->post('page', 1);
            $limit = request()->post('limit', 10);

            $obj = $this->M("bbs")
                ->alias('b')
                ->field('b.id, b.top, b.cate_id, b.title, u.nickname, u.head_img, substring(b.content, 1, 100) as summary, b.view_num as views, b.good_num as likes, b.bad_num as dislikes, b.comment_num as comments, b.create_time as time,b.uid, b.cover_src as cover, ur.role_id as role, bg.id as is_good')
                ->leftJoin('user_role ur', 'ur.uid = b.uid')
                ->leftJoin('bbs_good bg', 'bg.bid = b.id AND bg.uid = ' . $uid)
                ->leftJoin('category cate', 'b.cate_id = cate.id')
                ->join('user u', 'u.id = b.uid')
                ->order("b.top", "desc")
                ->order("b.top_time", "desc")
                ->order("b.id", "desc");

            if ($search != null) {
                $obj->whereOr([
                    [['b.title', 'like', '%' . $search . '%']],
                    [['b.content', 'like', '%' . $search . '%']]
                ]);
            }

            if (!empty($id)) {
                $obj->where([['b.cate_id', '=', $id]]);
            }

            $obj->where([['b.stat', '=', 1], ['cate.stat', '=', 1]])
                ->group('b.id, u.nickname, u.head_img, bg.id');

            $count = $obj->count();
            $list = $obj->order('b.id', 'desc')
                ->page($page, $limit)
                ->select()
                ->toArray();

            $data = [];
            $data['_extra'] = ['sum' => ['total' => $count]];

            foreach ($list as $v) {
                $liked = $v['is_good'] != null;
                $item = [
                    'id' => $v['id'],
                    'cate_id' => $v['cate_id'],
                    'uid' => $v['uid'],
                    'title' => $v['title'],
                    'summary' => $v['summary'],
                    'cover' => $v['cover'],
                    'time' => $v['time'],
                    'likes' => $v['likes'],
                    'dislikes' => $v['dislikes'],
                    'comments' => $v['comments'],
                    'views' => $v['views'],
                    'like' => $liked ? 1 : 0,
                    'top' => $v['top']
                ];
                $item['author'] = [
                    'nickname' => $v['nickname'],
                    'headurl' => $v['head_img'],
                    'role' => $v['role']
                ];
                $data[] = $item;
            }

            return pr(200, API_SUCCESS, $data);
        } catch (Exception $e) {
            return pr(301, $e->getMessage());
        }
    }

    /**
     * 帖子置顶
     * @param $id
     * @return Json
     */
    public function top($id): Json
    {
        $uid = $this->getUid();
        if (empty($uid)) return pr(302, API_NEED_LOGIN);
        $top = request()->post('top', 0, 'int');
        try {
            $data = $this->M("bbs")->field('uid')->where(['id' => $id])->find();
            if (!$this->checkAuth() && !$this->CheckAuthority($uid, '公告管理')) return pr(300, API_NO_AUTH);
            $this->M("bbs")->where(['id' => $id])->save(['top' => $top, 'top_time' => $top == 1 ? time() : 0]);
            return pr(200);
        } catch (DataNotFoundException | ModelNotFoundException | DbException $e) {
            return pr(300, API_DATA_NOT_FOUND);
        }
    }

    /**
     * 获取帖子列表
     * @param $id
     * @return Json
     */
    public function item($id): Json
    {
        try {
            $v = $this->M("bbs")
                ->alias('b')
                ->field('b.id,b.cate_id,b.title,u.id as uid,u.nickname,u.head_img,b.content as summary,b.good_num as likes,b.bad_num as dislikes,b.comment_num as comments,b.create_time as time,b.cover_src as cover,group_concat(ur.role_id) as role')
                ->leftJoin('user_role ur', 'ur.uid = b.uid')
                ->leftJoin('category cate', 'b.cate_id = cate.id')
                ->join('user u', 'u.id = b.uid')
                ->where([['b.id', '=', $id], ['b.stat', '=', 1], ['cate.stat', '=', 1]])
                ->group('b.id')
                ->find();
            $item = ['id' => $v['id'], 'cate_id' => $v['cate_id'], 'title' => $v['title'], 'summary' => $v['summary'], 'cover' => $v['cover'], 'time' => $v['time'], 'likes' => $v['likes'], 'comments' => $v['comments']];
            $item['author'] = ['uid' => $v['uid'],'nickname' => $v['nickname'], 'headurl' => $v['head_img'], 'role' => $v['role']];
            //浏览数+1
            $this->M("bbs")->where('id', '=', $id)->setInc('view_num');
            // $item['_extra'] = ['sum'=>['total'=>$comments]];
            return pr(200, API_SUCCESS, $item);
        } catch (Exception $e) {
            return pr(301, $e->getMessage());
        }
    }
    /**
     * 获取帖子回复列表
     */

    public function reply_list($id): Json
    {
        //同时返回是否点赞
        $page = request()->post('page', 1);
        $limit = request()->get('limit', 10);
        $sort = request()->get('order', 0);
        $obj = $this->M('bbs_reply')
            ->alias('br')
            ->field('br.id,br.uid,u.nickname,u.head_img,br.content,br.create_time,br.reply_id,br.comment_num as comments, br.good_num as likes,br.bad_num as dislikes,group_concat(ur.role_id) as role,bg.id as is_good')
            ->leftJoin('user_role ur', 'ur.uid = br.uid')
            ->leftJoin('bbs_reply_good bg', 'bg.rid = br.id')
            ->join('user u', 'u.id = br.uid')
            ->where([['br.bid', '=', $id], ["br.reply_id", "=", 0], ['br.stat', '=', 1]])
            ->group('br.id,bg.id');

        if ($sort == 0) $obj->order('br.create_time', 'desc');
        else $obj->order('br.good_num', 'desc');
        $list = $obj->page($page, $limit)->select()->toArray();
        //获取总数
        $count = $obj->count();
        $data = [];
        foreach ($list as $v) {
            $like = 0;
            if ($v["is_good"] != null) $like = 1;
            $children = $this->reply_to_list($v["id"], $page, $limit);
            $author = ["nickname" => $v["nickname"], "headurl" => $v["head_img"], "role" => $v['role']];
            $item = ["id" => $v['id'], "uid" => $v["uid"], "likes" => $v["likes"], "dislikes" => $v["dislikes"], "time" => $v["create_time"], "content" => $v["content"], "author" => $author, "total" => $v["comments"], "children" => $children, "like" => $like];
            $data[] = $item;
        }
        $data['_extra'] = ['sum' => ['total' => $count]];
        return pr(200, API_SUCCESS, $data);
    }

    /**
     * 获取回复 帖子回复列表
     */

    public function reply_to_list($id, $page = 1, $limit = 10): array
    {
        $list = $this->M('bbs_reply')
            ->alias('br')
            ->field('br.id,br.uid,br.content,br.create_time,br.reply_id,br.comment_num as comments,br.good_num as likes,br.bad_num as dislikes,u.nickname,u.head_img,u.id as uid,ifnull(u2.id,0) as to_uid,u2.nickname as to_nickname,u2.head_img as to_head_img,group_concat(ur.role_id) as role,group_concat(ur2.id) as to_role')
            ->join('user u', 'u.id = br.uid')
            ->leftJoin('user u2', 'u2.id = br.to_uid')
            ->leftJoin('user_role ur', 'ur.uid = br.uid')
            ->leftJoin('user_role ur2', 'ur.uid = br.to_uid')
            ->where([['br.reply_id', '=', $id], ['br.stat', '=', 1]])
            ->group('br.id')
            ->page($page, $limit)
            ->select()
            ->toArray();
        $data = [];
        foreach ($list as $v) {
            // 此处停用多级回复
            $children = [];
            // $children=$this->reply_to_list($v["id"],$page,$limit);
            $author = ["nickname" => $v["nickname"], "headurl" => $v["head_img"], "role" => $v['role']];
            $toAuthor = ["nickname" => $v["to_nickname"], "headurl" => $v["to_head_img"], "role" => $v['to_role']];
            $item = [
                "id" => $v['id'], "uid" => $v["uid"], "likes" => $v["likes"], "dislikes" => $v["dislikes"], "time" => $v["create_time"], "content" => $v["content"],
                "to_author" => $v['to_uid'] > 0 ? $toAuthor : null, "author" => $author, "children" => $children
            ];
            $data[] = $item;
        }
        return $data;
    }

    public function good($id): Json
    {
        $uid = $this->getUid();
        if (empty($uid)) return pr(302, API_NEED_LOGIN);
        $f = $this->M('bbs_good')->where([['bid', '=', $id], ['uid', '=', $uid]])->field('id')->find();
        if (empty($f)) {
            $this->M('bbs')->where('id', '=', $id)->setInc('good_num');
            $this->M('bbs_good')->insert(['uid' => $uid, 'bid' => $id]);
            return pr(200, '点赞成功', 1);
        } else {
            $this->M('bbs')->where('id', '=', $id)->setDec('good_num');
            $this->M('bbs_good')->where(['uid' => $uid, 'id' => $f['id']])->delete();
            return pr(200, '取消点赞', -1);
        }
    }

    public function reply_good($id): Json
    {
        $uid = $this->getUid();
        if (empty($uid)) return pr(302, API_NEED_LOGIN);
        $f = $this->M('bbs_reply_good')->where([['rid', '=', $id], ['uid', '=', $uid]])->field('id')->find();
        if (empty($f)) {
            $this->M('bbs_reply')->where('id', '=', $id)->setInc('good_num');
            $this->M('bbs_reply_good')->insert(['uid' => $uid, 'rid' => $id]);
            return pr(200, '点赞成功', 1);
        } else {
            $this->M('bbs_reply')->where('id', '=', $id)->setDec('good_num');
            $this->M('bbs_reply_good')->where('id', '=', $f['id'])->delete();
            return pr(200, '取消点赞', -1);
        }
    }

    /**
     * 发布帖子
     */
    public function add(): Json
    {
        $uid = $this->getUid();
        if (empty($uid)) return pr(302, API_NEED_LOGIN);
        $title = request()->post('title');
        $content = request()->post('content');
        $cate_id = request()->post('cate_id');
        $cover_src = request()->post('cover_src');
        $id = request()->post('id', 0, 'int');
        if (mb_strlen($title, "utf-8") > 30) return pr(301, '标题过长');

        try {
            if ($id > 0) {
                $data = [
                    'title' => $title,
                    'cover_src' => $cover_src,
                    'content' => $content,
                    'last_edit_time' => time(),
                ];
                $this->M('bbs')->where('id', '=', $id)->where('uid', '=', $uid)->update($data);
            } else {
                $data = [
                    'uid' => $uid,
                    'title' => $title,
                    'content' => $content,
                    'cate_id' => $cate_id,
                    'cover_src' => $cover_src,
                    'create_time' => time(),
                    'last_edit_time' => time(),
                    'stat' => 1,
                    'comment_num' => 0,
                    'reply_num' => 0,
                    'view_num' => 0
                ];
                //板块发帖数+1
                $this->M('category')->where('id', '=', $cate_id)->setInc('postnum');
                $this->M('bbs')->insert($data);
            }

            return pr(200, '发布成功');
        } catch (Exception $e) {
            return pr(301, '发布失败:' . $e->getMessage());
        }
    }

    /**
     * 编辑帖子
     */
    public function edit(): Json
    {
        $uid = $this->getUid();
        if (empty($uid)) return pr(302, API_NEED_LOGIN);
        $id = request()->post('id');
        $title = request()->post('title');
        $content = request()->post('content');
        $cate_id = request()->post('cate_id');
        $cover_src = request()->post('cover_src');
        $data = [
            'uid' => $uid,
            'title' => $title,
            'content' => $content,
            'cate_id' => $cate_id,
            'cover_src' => $cover_src,
            'last_edit_time' => time(),
        ];
        try {
            $this->M('bbs')->where('id', '=', $id)->update($data);
            return pr(200, '编辑成功');
        } catch (Exception $e) {
            return pr(301, '编辑失败:' . $e->getMessage());
        }
    }


    /**
     * 发布评论
     */
    public function reply(): Json
    {
        $uid = $this->getUid();
        if (empty($uid)) return pr(302, API_NEED_LOGIN);
        $content = request()->post('content');
        $bid = request()->post('bid', 0);
        $reply_id = request()->post('reply_id', 0);
        $to_reply_id = request()->post('to_reply_id', 0);
        $data = [
            'uid' => $uid,
            'content' => $content,
            'reply_id' => $reply_id,
            'create_time' => time(),
            'stat' => 1,
        ];
        try {
            if ($bid > 0) { //对帖子回复
                $b = $this->M('bbs')->field('cate_id')->where('id', '=', $bid)->find();
                //板块回复数+1
                $this->M('category')->where('id', '=', $b['cate_id'])->setInc('interaction');
                //帖子评论数+1
                $this->M('bbs')->where('id', '=', $bid)->setInc('comment_num');
                $data['bid'] = $bid;
                $this->M('bbs_reply')->insert($data);
            } else if ($reply_id > 0) { //对评论回复
                $br = $this->M('bbs_reply')->field('bid,uid')->where('id', '=', $reply_id)->find();
                $b = $this->M('bbs')->field('cate_id')->where('id', '=', $br['bid'])->find();
                //评论回复数+1
                $this->M('bbs_reply')->where('id', '=', $reply_id)->setInc('comment_num');
                //帖子评论数+1
                $this->M('bbs')->where('id', '=', $br['bid'])->setInc('comment_num');
                //板块回复数+1
                $this->M('category')->where('id', '=', $b['cate_id'])->setInc('interaction');
                $data['reply_id'] = $reply_id;
                $data['bid'] = $br['bid'];
                if ($to_reply_id > 0) {
                    $br2 = $this->M('bbs_reply')->field('uid')->where('id', '=', $to_reply_id)->find();
                    $data['to_uid'] = $br2['uid'];
                }
                $this->M('bbs_reply')->insert($data);
            }
            return pr(200, '评论成功');
        } catch (Exception $e) {
            return pr(301, '评论失败', $e->getMessage());
        }
    }

    /**
     * 删除帖子
     */
    public function del(): Json
    {
        $uid = $this->getUid();
        if (empty($uid)) return pr(302, API_NEED_LOGIN);
        $id = request()->post('id');
        $type = request()->post('type', 0, 'int'); //0软删除1硬删除
        if (empty($id)) return pr(302, API_FAIL);
        try {
            if ($type == 0) {
                $this->M('bbs')->where('id', '=', $id)->where('uid', '=', $uid)->update(['stat' => 0]);
                $this->M('bbs_reply')->where('bid', '=', $id)->where('uid', '=', $uid)->update(['stat' => 0]);
            } else {
                $this->M('bbs')->where('id', '=', $id)->where('uid', '=', $uid)->delete();
                $this->M('bbs_reply')->where('bid', '=', $id)->where('uid', '=', $uid)->delete();
            }
            return pr(200, '删除成功');
        } catch (Exception $e) {
            return pr(301, '删除失败');
        }
    }

    /**
     * 帖子锁定
     * @return Json
     */
    public function lock_item(): Json
    {
        $uid = $this->getUid();
        if (empty($uid)) return pr(302, API_NEED_LOGIN);
        $id = $this->request->post('id', 0, 'int');
        try {
            $this->M("bbs")->where('id', '=', $id)->where('uid', '=', $uid)->update(['stat' => 0]);
            return pr(200, '锁定成功');
        } catch (DbException $e) {
            return pr(300, API_FAIL);
        }
    }

    /**
     * 回复删除
     * @param $id
     * @return Json
     */
    public function del_reply($id): Json
    {
        $uid = $this->getUid();
        if (empty($uid)) return pr(302, API_NEED_LOGIN);
        try {
            $data = $this->M("bbs_reply")->field("uid")->where('id', $id)->find();
            if ($data['uid'] != $this->getUid() && !$this->checkAuth()) {
                return pr(300, API_NO_AUTH);
            } else {
                $this->M("bbs_reply")->where('id', $id)->save(['stat' => 0]);
                return pr(200, '已成功删除');
            }
        } catch (DataNotFoundException | ModelNotFoundException | DbException $e) {
            return pr(300, API_FAIL);
        }
    }
    
    private function checkAuth(): bool
    {
        $uid = $this->getUid();
        if (empty($uid)) return false;
        try {
            $check = $this->M('user_role')->where('uid', '=', $uid)->where('role_id', '=', 1)->find();
            if (empty($check)) return false;
            else return true;
        } catch (DataNotFoundException | ModelNotFoundException | DbException $e) {
            return false;
        }
    }
    
      //检查权限
     private function CheckAuthority($uid, $type): bool
     {
        if (empty($uid)) return false;
        try {
            $roleList = $this->M('user_role')->where('uid', '=', $uid)->select()->toArray();
            if (empty($roleList)) return false;
            foreach($roleList as $v){
                if($v["role_id"] == 1 || $v["role_id"] == 2) return true;
                switch($type){
                    case "账户管理": if($v["role_id"] == 18) return true; break;
                    case "公告管理": if($v["role_id"] == 17) return true; break;
                    case "服列表管理": if($v["role_id"] == 16) return true; break;
                    case "资源管理": if($v["role_id"] == 13) return true; break;
                    case "轮值管理": if($v["role_id"] == 14) return true; break;
                }
            }
            return false;
        } catch (DataNotFoundException | ModelNotFoundException | DbException $e) {
            return false;
        }
     }
}
